﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MyNoteBook
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
            ///初始化栈，这是使用前必须的
            this.contentStack = new Stack<string>();
            frmSearch frm = new frmSearch();
            frm.strMyText = "Hello World";
            frm.Show();
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {

        }
        /// <summary>
        /// 打开文件菜单项相应程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 打开ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog openFileDialog = new OpenFileDialog();
                openFileDialog.Title = "打开文本文件";
                openFileDialog.FileName = "*.txt";
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    FileStream fileStream = new FileStream(openFileDialog.FileName, FileMode.Open);
                    StreamReader streamReader = new StreamReader(fileStream, Encoding.Default);
                    this.txtMainContent.Text = streamReader.ReadToEnd();
                    streamReader.Close();
                    fileStream.Close();
                    ///更新存储的文件名
                    this.fileName = openFileDialog.FileName;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            ///清空栈
            this.contentStack.Clear();
        }

        private void 新建NToolStripMenuItem1_MouseDown(object sender, MouseEventArgs e)
        {

        }
        /// <summary>
        /// 文件名属性，用于存储文件名
        /// </summary>
        private string mfileName;
        public string fileName
        {
            get { return mfileName; }
            set
            {
                mfileName = value;
                if (!string.IsNullOrEmpty(value))
                    this.Text = string.Format("{0}-记事本", mfileName);
                else
                    this.Text = "无标题-记事本";
            }
        }
        /// <summary>
        /// 新建菜单相应程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 新建NToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            //设置文本内容为空
            this.txtMainContent.Text = "";
            this.fileName = "";
            ///清空栈
            this.contentStack.Clear();
        }
        /// <summary>
        /// 文件另存为响应程序，如果未保存的新文件也可调用该程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 另存为AToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                SaveFileDialog saveFileDialog = new SaveFileDialog();
                saveFileDialog.Title = "保存文本文件";
                saveFileDialog.FileName = "*txt";
                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    FileStream fileStream = new FileStream(saveFileDialog.FileName, FileMode.Create);
                    StreamWriter streamWriter = new StreamWriter(fileStream, Encoding.Default);
                    streamWriter.Write(this.txtMainContent.Text);
                    streamWriter.Close();
                    fileStream.Close();
                    ///更新存储的文件名
                    this.fileName = saveFileDialog.FileName;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        /// <summary>
        /// 保存菜单护理程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 保存SToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(this.fileName))
                另存为AToolStripMenuItem_Click(null, null);//文件名不存在直接调用另存为
            else
                try
                {
                    ///文件名存在，直接存盘
                    FileStream filestream = new FileStream(this.fileName, FileMode.Create);
                    StreamWriter streamWriter = new StreamWriter(filestream, Encoding.Default);
                    streamWriter.Write(this.txtMainContent.Text);
                    streamWriter.Close();
                    filestream.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

        }
        /// <summary>
        /// 页面设置响应程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 页面设置UToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.pageSetupDialog1.ShowDialog();
        }
        /// <summary>
        /// 文档打印程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            ///将文档内容打印出来，出于简化的目的，这里只打印第一页的内容
            //多页打印的问题，请同学们自己解决
            ///Graphics可以理解为打印时的那支画笔
            Graphics g = e.Graphics;
            ///打印的画刷设置，这些是黑色实践
            Brush brush = new SolidBrush(Color.Black);
            ///打印字体，使用编辑框里同一字体，包括大小也一样
            Font font = this.txtMainContent.Font;
            g.DrawString(this.txtMainContent.Text, font, brush, new RectangleF(0, 0, e.PageBounds.Width, e.PageBounds.Height));
        }
        /// <summary>
        /// 打印菜单响应程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 打印PToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.printDialog1.ShowDialog() == DialogResult.OK)
            {
                ///将打印设置传给打印文档
                this.printDocument1.PrinterSettings = this.printDialog1.PrinterSettings;
                ///将页面设置传给打印文档
                this.printDocument1.DefaultPageSettings = this.pageSetupDialog1.PageSettings;
                ///开始打印
                this.printDocument1.Print();
            }
        }
        /// <summary>
        /// 退出菜单的响应程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 退出XToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        /// <summary>
        /// 文件内容堆栈
        /// </summary>
        public Stack<string> contentStack { get; set; }
        /// <summary>
        /// 撤销菜单响应程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 撤销ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.contentStack.Count > 0)
                this.contentStack.Pop();
            if (this.contentStack.Count > 0)
                this.txtMainContent.Text = this.contentStack.Pop();
        }
        /// <summary>
        /// 键盘按键事件，由于没有SelectionChange事件，只能采用这个事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtMainContent_KeyDown(object sender, KeyEventArgs e)
        {
            CheckSelection();
        }
        /// <summary>
        /// 鼠标抬起事件，由于没有SelectionChanged事件，只能采用这个事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtMainContent_MouseUp(object sender, MouseEventArgs e)
        {
            CheckSelection();
        }
        /// <summary>
        /// 检查文本框中的选择文字的状态，决定菜单项的可用性
        /// </summary>
        private void CheckSelection()
        {
            ///剪切板中有文字
            if (Clipboard.ContainsText())
            {
                this.粘贴ToolStripMenuItem.Enabled = true;
            }
            else
            {
                this.粘贴ToolStripMenuItem.Enabled = false;
            }

            if (this.txtMainContent.SelectedText == "")
            {
                ///没有选择的文字
                this.剪切ToolStripMenuItem.Enabled = false;
                this.复制ToolStripMenuItem.Enabled = false;
                this.删除ToolStripMenuItem.Enabled = false;
            }
            else
            {
                ///有选择的文字
                this.剪切ToolStripMenuItem.Enabled = true;
                this.复制ToolStripMenuItem.Enabled = true;
                this.删除ToolStripMenuItem.Enabled = true;

                ///计算光标行列数，显示在状态栏里
                ///strLeft为光标前的字串
                string strLeft = this.txtMainContent.Text.Substring(0, this.txtMainContent.SelectionStart);

                strLeft = "\r\t" + strLeft;
                ///最后一个回车出现的位置
                int lastIndex = strLeft.LastIndexOf('\n');
                ///光标在本行内所在的行数
                int intCol = this.txtMainContent.SelectionStart - lastIndex + 1;
                ///计算行数要数前面的回车数量
                var arrayString = strLeft.Split('\n');
                int intRow = arrayString.Length - 1;
                ///设置显示
                this.toolStripStatusLabel_Message.Text = String.Format("第{0}行，第{0}列", intRow, intCol);
            }
        }

        /// <summary>
        /// 剪切菜单项处理程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 剪切ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.txtMainContent.SelectedText != "")
            {
                Clipboard.SetText(this.txtMainContent.SelectedText);
                this.txtMainContent.SelectedText = "";
                CheckSelection();
            }
        }
        /// <summary>
        /// 复制菜单项处理程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 复制ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.txtMainContent.SelectedText != "")
            {
                Clipboard.SetText(this.txtMainContent.SelectedText);
                CheckSelection();
            }
        }
        /// <summary>
        /// 菜单项处理程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 粘贴ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string strInsertText = Clipboard.GetText();
            this.txtMainContent.SelectedText = strInsertText;
        }
        /// <summary>
        /// 删除菜单项处理程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 删除ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.txtMainContent.SelectedText = "";
        }
        /// <summary>
        /// 查询窗口，设为属性是为了防止重复开这一窗口
        /// </summary>
        private static frmSearch frmsearch { get; set; }

        private void 查找ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmsearch = new frmSearch();
            frmsearch.Search += frm_Search;
            frmsearch.Show();
        }
        /// <summary>
        /// 用于存储查询条件的结构
        /// </summary>
        public struct SearchContent
        {
            public string Text;
            public bool IsUp;
            public bool IsCaseSensitive;

            public SearchContent(string strSearchText, bool mIsUp, bool mIsCaseSensitive)
            {
                Text = strSearchText;
                IsUp = mIsUp;
                IsCaseSensitive = mIsCaseSensitive;
            }
        }

        public SearchContent searchContent { get; set; }

        /// <summary>
        /// 当frmSearch激发查询时的响应程序
        /// </summary>
        /// <param name="strSearchText"></param>
        /// <param name="IsUp"></param>
        /// <param name="IsCaseSensitive"></param>
        private void frm_Search(string strSearchText, bool IsUp, bool IsCaseSensitive)
        {
            ///先将查询条件存储起来
            this.searchContent = new SearchContent(strSearchText, IsUp, IsRestrictedWindow);
            ///开始查询
            searchNext();
        }

        private void searchNext()
        {
            ///搜索结果的位置
            int intAns = -1;

            ///光标所在的位置
            int indexNow;
            ///要搜索的字串是光标前还是光标后，由searchContent.IsUp决定
            if (this.searchContent.IsUp)
            {
                ///向上搜索
                indexNow = this.txtMainContent.SelectionStart;
                string strSearchString = this.txtMainContent.Text.Substring(0, indexNow);
                ///大小写是否敏感问题
                if (this.searchContent.IsCaseSensitive)
                    intAns = strSearchString.LastIndexOf(this.searchContent.Text, StringComparison.CurrentCulture);
                else
                    intAns = strSearchString.LastIndexOf(this.searchContent.Text, StringComparison.CurrentCultureIgnoreCase);
            }
            else
            {
                ///向下搜索
                indexNow = this.txtMainContent.SelectionStart + this.txtMainContent.SelectionLength;
                string strSearchString = this.txtMainContent.Text.Substring(indexNow);
                ///大小写是否敏感问题
                if (this.searchContent.IsCaseSensitive)
                    intAns = strSearchString.IndexOf(this.searchContent.Text, StringComparison.CurrentCulture);
                else
                    intAns = strSearchString.LastIndexOf(this.searchContent.Text, StringComparison.CurrentCultureIgnoreCase);
            }
            if (intAns < 0)
                MessageBox.Show(string.Format("找不到“{0}”", searchContent.Text));
            //没找到
            else
            {
                ///激活本窗口，不然无法显示搜索结果
                this.Activate();
                ///如果是向下搜索，需要加上光标开始时的坐标
                if (!searchContent.IsUp)
                    intAns += indexNow;
                ///设定搜索结果
                this.txtMainContent.SelectionStart = intAns;
                this.txtMainContent.SelectionLength = this.searchContent.Text.Length;
            }
        }
        /// <summary>
        /// 查找下一个菜单项响应程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 查找下一个ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(this.searchContent.Text))
                searchNext();
            else
                查找ToolStripMenuItem_Click(null, null);//如果没有开始过搜索，则直接调用搜索菜单程序
        }
        /// <summary>
        /// 全选功能，如果明白了上面的SelectionStart和SelectionLength,这里就很简单了
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 全选AToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.txtMainContent.SelectionStart = 0;
            this.txtMainContent.SelectionLength = this.txtMainContent.Text.Length;
        }
        /// <summary>
        /// 时间日期菜单项响应程序，就是将当前时间插入光标位置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 时间日期DToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.txtMainContent.SelectionLength = 0;
            this.txtMainContent.SelectedText = System.DateTime.Now.ToString();
            this.txtMainContent.SelectionLength = 0;
        }
        /// <summary>
        /// 自动换行切换相应程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 自动换行ToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
        {
            if (this.自动换行ToolStripMenuItem.Checked)
            {
                ///自动换行状态
                this.转到ToolStripMenuItem.Enabled = false;
                this.状态栏ToolStripMenuItem.Checked = false;
                this.状态栏ToolStripMenuItem.Enabled = false;
                ///自动换行
                this.txtMainContent.WordWrap = true;
                ///输入区只包含纵向滚动条
                this.txtMainContent.ScrollBars = ScrollBars.Vertical;
            }
            else
            {
                ///不自动换行状态
                this.转到ToolStripMenuItem.Enabled = true;
                this.状态栏ToolStripMenuItem.Enabled = true;
                ///不自动换行
                this.txtMainContent.WordWrap = false;
                ///输入区包括双向滚动条
                this.txtMainContent.ScrollBars = ScrollBars.Both;
            }
        }
        /// <summary>
        /// 状态栏菜单项响应程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 状态栏SToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.toolStripStatusLabel1.Visible = this.状态栏ToolStripMenuItem.Checked;
        }

        private void 转到ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmGoTo frm = new frmGoTo();
            if (frm.ShowDialog() == DialogResult.OK)
            {
                int intLine;
                if (int.TryParse(frm.Tag.ToString(), out intLine))//要防止用户输入的不是整数
                {
                    if (intLine > 0)
                    {
                        int intPosition = 0;
                        if (intLine > 1)
                        {
                            for (int i = 1; i < intLine; i++)
                            {
                                int intNext = this.txtMainContent.Text.IndexOf('\n', intPosition);
                                if (intNext >= 0)
                                {
                                    intPosition = intNext + 1;
                                }
                                else
                                    break;
                            }
                        }
                        if (intPosition >= 0)
                        {
                            ///存在指定的行
                            this.txtMainContent.SelectionStart = intPosition;
                            this.txtMainContent.SelectionLength = 0;
                            ///控件的内容滚到光标位置
                            this.txtMainContent.ScrollToCaret();
                            ///刷新状态栏显示
                            CheckSelection();
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 字体菜单响应程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 字体FToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(this.fontDialog1.ShowDialog()==DialogResult.OK)
            {
                this.txtMainContent.Font = this.fontDialog1.Font;
            }
        }
    }
}
        








